package com.oneinlet

import java.time.Duration
import java.time.LocalDateTime
import java.time.format.DateTimeFormatter
import java.time.temporal.ChronoUnit


/**
 * Created by WangZiHe on 19-6-10
 * QQ/WeChat:648830605
 * QQ-Group:368512253
 * Blog:www.520code.net
 * Github:https://github.com/yancheng199287
 */

object YCLocalDateTime {

    enum class DateFormat(val style: String) {
        YYYY_MM_DD_HH_MM_SS("yyyy-MM-dd HH:mm:ss"),
        YYYY_MM_DD("yyyy-MM-dd"),
        YYYY_MM_DD_HH_MM_SS_SSS("yyyy-MM-dd HH:mm:ss.SSS"),
        YYYY_YEAR_MM_MONTH_DD_DAY("yyyy年MM月dd日"),
        YYYYMMDDHHMMSS("yyyyMMddHHmmss"),
    }

    enum class TimeUnit {
        YEAR,
        MONTH,
        DAY,
        HOUR,
        MINUTE,
        SECOND,
        MILLISECOND
    }

    enum class TimeNode {
        START,
        END
    }

    /**
     * 获取一个当前时间，将时间进行默认格式化
     * @return  返回一个默认格式化后的日期字符串 yyyy-MM-dd HH:mm:ss
     * */
    fun toDefaultFormatNow(): String {
        return LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))
    }

    /**
     * 将时间进行格式化
     * @return  返回一个默认格式化后的日期字符串 yyyy-MM-dd HH:mm:ss
     * */
    fun formatDefault(localDateTime: LocalDateTime): String {
        return localDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))
        // return DateTimeFormatter.ofPattern(DateFormat.YYYY_MM_DD_HH_MM_SS.style).format(localTime)
    }


    /**
     * 将时间进行格式化
     * @param style  保证扩展性，接受一个格式化日期字符串
     * @return  返回一个格式化后的日期字符串
     * */
    fun format(localDateTime: LocalDateTime, style: String): String {

        return localDateTime.format(DateTimeFormatter.ofPattern(style))
    }


    /**
     * 将字符串时间解析成日期对象,默认的时间格式是 yyyy-MM-dd HH:mm:ss
     * @param localDateTimeStr  保证扩展性，接受一个格式化日期枚举
     * @return  返回一个日期对象
     * */
    fun parserDefault(localDateTimeStr: String): LocalDateTime {
        return LocalDateTime.parse(localDateTimeStr, DateTimeFormatter.ofPattern(DateFormat.YYYY_MM_DD_HH_MM_SS.style))
    }


    /**
     * 将字符串时间解析成日期对象,默认的时间格式是 yyyy-MM-dd HH:mm:ss
     * @param localDateTimeStr  时间字符串
     * @param style  时间格式
     * @return  返回一个日期对象
     * */
    fun parser(localDateTimeStr: String, style: String): LocalDateTime {
        return LocalDateTime.parse(localDateTimeStr, DateTimeFormatter.ofPattern(style))
    }


    /**
     * 对时间进行差值计算,左边时间靠前，右边时间靠后
     * @param leftLocalDateTime  接收一个LocalDateTime对象
     * @param rightLocalDateTime  接收一个LocalDateTime对象
     * @param timeUnit  接收一个时间单位，返回该对应单位的差值
     * @return  返回一个格式化后的日期字符串
     * */
    fun subBetweenTime(leftLocalDateTime: LocalDateTime, rightLocalDateTime: LocalDateTime, timeUnit: TimeUnit): Long {
        return when (timeUnit) {
            TimeUnit.YEAR -> {
                ChronoUnit.YEARS.between(leftLocalDateTime, rightLocalDateTime)
            }
            TimeUnit.MONTH -> {
                ChronoUnit.MONTHS.between(leftLocalDateTime, rightLocalDateTime)
            }
            TimeUnit.DAY -> {
                ChronoUnit.DAYS.between(leftLocalDateTime, rightLocalDateTime)
            }
            TimeUnit.HOUR -> {
                Duration.between(leftLocalDateTime, rightLocalDateTime).toHours()
            }
            TimeUnit.MINUTE -> {
                Duration.between(leftLocalDateTime, rightLocalDateTime).toMinutes()
            }
            TimeUnit.SECOND -> {
                Duration.between(leftLocalDateTime, rightLocalDateTime).seconds
            }
            TimeUnit.MILLISECOND -> {
                Duration.between(leftLocalDateTime, rightLocalDateTime).toMillis()
            }
        }
    }

    /**
     * 判断当前时间是否在这个区间时间范围内，默认是大于等于起始时间并且小于等于结束时间
     * @param time  计划目标时间
     * @param startTime  起始时间
     * @param endTime  结束时间
     * @return  返回布尔值，true即在此范围区间内，false不在
     * */
    fun timeAtBetween(time: LocalDateTime, startTime: LocalDateTime, endTime: LocalDateTime): Boolean {
        return time in startTime..endTime
    }


    /**
     *  获取所在时间内当天的开始或者结束时间节点
     * @param localDateTime  指定当前时间
     * @param timeNode  时间节点，是起点时间还是结束的时间
     * */
    fun getTimeNodeWithDay(localDateTime: LocalDateTime, timeNode: TimeNode): LocalDateTime {
        return when (timeNode) {
            TimeNode.START -> {
                localDateTime.withHour(0).withMinute(0).withSecond(0)
            }
            TimeNode.END -> {
                localDateTime.withHour(23).withMinute(59).withSecond(59)
            }
        }
    }

    /**
     *  将秒数转换为时分秒，通常用于倒计时操作
     * @param secondParameter  指定当前秒数，必须是大于0
     * @return LocalDateTime  返回一个时间 如 02:30:59sha
     * */
    fun secondToTime(secondParameter: Int): String {
        YCAssert.isTrue(secondParameter >= 0, "second must not be less than 0 ")
        val hour: Int = secondParameter / 3600
        val minute: Int = (secondParameter - hour * 3600) / 60
        val second: Int = secondParameter - hour * 3600 - minute * 60
        return "$hour:$minute:$second"
    }


}